/*
    类型转换、检测
*/

var typeUtils = (function () {

    var __class = function () { this.__self = this; };
    __class.prototype.getSelf = function (str) {
        return this.__self;
    }

    /*
        *  检测是否是数组、对象形式的类数组
        *  @param  o Any 检测对象
        *  @retrun boolean 是否是数组、对象形式的类数组
    */
    __class.prototype.isArray = function (o) {
        if (o &&  //o非null undefined
            typeof o === "object" &&  //o是对象
            isFinite(o.length) && //o.length是有限数值
            o.length >= 0 &&  //o.length是非负值
            o.length === Math.floor(o.length) &&  //o.length<2^32
            o.length < 4294967296) {  //o是类数组对象
            return true;
        } else {
            return false;
        }
    }

    /*
        *  json对象转字符串
        *  @param value Object 要转换的对象
        *  @param symbol String 可选参数 字符之间的分隔符，如不需要传入 ''
        *  @retrun String 字符串
    */
    __class.prototype.objectToString = function (value, symbol) {
        if (!symbol) { symbol = '' }
        return Array.prototype.join.call(value, symbol);
    }

    /*
        *  json对象转数组
        *  @param value Object 要转换的对象
        *  @retrun Array 数组
    */
    __class.prototype.objectToArray = function (value) {
        return Array.prototype.slice.call(value, 0);
    }

    /*
        *  json对象转数组，且每个属性值转为大写字母
        *  @param value Object 要转换的对象
        *  @retrun Array 数组
    */
    __class.prototype.objectToUpperCase = function (value) {
        return Array.prototype.map.call(value, function (x) {
            return x.toUpperCase();
        });
    }

    /*
        *  字符串以指定字符作为间隔符
        *  @param value String 要转换的字符串
        *  @param symbol String 字符之间的分隔符
        *  @retrun String 字符串
    */
    __class.prototype.stringSymbol = function (value, symbol) {
        return Array.prototype.join.call(value, symbol);
    }

    /*
        *  字符串截取
        *  @param value String 要转换的字符串
        *  @param matching RegExp 正则表达式
        *  @retrun String 字符串
    */
    __class.prototype.stringFilter = function (value, matching) {
        return Array.prototype.filter.call(value, function (x) {
            return x.match(matching);
        }).join().replace(/,/g, "");
    }

    /*
        *  数组每个元素转为字符串
        *  @param array Array 要转换的数组
        *  @retrun Array 数组
    */
    __class.prototype.toStringArray = function (array) {
        return array.map(String);
    }

    /*
        *  数组每个元素转为首字母大写
        *  @param array Array 要转换的数组
        *  @retrun Array 数组
    */
    __class.prototype.toTitleCase = function (array) {
        return array.map(function (x) {
            return x.charAt(0).toUpperCase() + x.slice(1).toLowerCase();
        });
    }

    /*
        *  字符串数组转换为数字数组
        *  @param array Array 要转换的数组
        *  @retrun Array 数组
    */
    __class.prototype.toNumberArray = function (array) {
        return array.map(function (val) {
            return parseFloat(val);
        });
    }

    /*
        *  数组求和、阶乘、求和且每个元素四舍五入
        *  @param array Array 要转换的数组
        *  @param flag String 切换模式，sum为求和且四舍五入、fact为阶乘、默认只求和
        *  @retrun Number 数字
    */
    __class.prototype.arrayToNumber = function (array, flag) {
        array = this.__self.toNumberArray(array);
        var re = 1;
        if (flag == 'sum') {
            return this.__self.keepTwoDecimal(array.reduce(function (x, y) {
                return x + Math.round(y);
            }));
        } else if (flag == 'fact') {
            return this.__self.keepTwoDecimal(array.reduce(function (x, y) {
                return x * y;
            }));
        } else {
            return this.__self.keepTwoDecimal(array.reduce(function (x, y) {
                return x + y;
            }));
        }
    }

    //四舍五入保留2位小数（若第二位小数为0，则保留一位小数）
    __class.prototype.keepTwoDecimal = function (num) {
        var result = parseFloat(num);
        if (isNaN(result)) {
            alert('传递参数错误，请检查！');
            return false;
        }
        result = Math.round(num * 100) / 100;
        return result;
    }
    //四舍五入保留2位小数（不够位数，则用0替补）
    __class.prototype.keepTwoDecimalFull = function (num) {
        var result = parseFloat(num);
        if (isNaN(result)) {
            alert('传递参数错误，请检查！');
            return false;
        }
        result = Math.round(num * 100) / 100;
        var s_x = result.toString();
        var pos_decimal = s_x.indexOf('.');
        if (pos_decimal < 0) {
            pos_decimal = s_x.length;
            s_x += '.';
        }
        while (s_x.length <= pos_decimal + 2) {
            s_x += '0';
        }
        return s_x;
    }

    /*
        *  保留奇数或偶数
        *  @param array Array 要转换的数组
        *  @param flag String 存在则为奇数、默认为偶数
        *  @retrun Array 转换后的数组
    */
    __class.prototype.arrayToOddEven = function (array, flag) {
        return array.filter(function (x) {
            if(flag){
                return x % 2 == 1;
            }
            return x % 2 == 0;   //表达式返回false则被过滤
        });
    }

    /*
        *  删除为空的数组元素
        *  @param array Array 要转换的数组
        *  @retrun Array 转换后的数组
    */
    __class.prototype.arrayFilterEmpty = function (array) {
        return array.filter(function (s) {
            if(typeof s == 'number'){
                return s;
            }
            return s && s.trim();   // 注意：IE9以下的版本没有trim()方法
        });
    }

    /*
        *  去除数组重复元素
        *  @param array Array 要转换的数组
        *  @retrun Array 转换后的数组
    */
    __class.prototype.arrayRemoveDuplication = function (array) {
        return array.filter(function (item, index, arr) {
            return arr.indexOf(item) === index;   //在数组中找到当前元素，下标 != 当前下标 ，都过滤
        });
    }

    /*
        *  数组排序
        *  @param array Array 要排序的数组
        *  @param type Number 排序类型，2为倒序，3为不区分大小写排序，默认正序
        *  @param flag boolean 可选参数，如果为true则克隆一份，不改变原数组
        *  @retrun Array 排序后的数组
    */
    __class.prototype.sort = function (array, type, flag) {
        var newArray;
        if(flag){
            newArray = this.__self.cloneObj(array);
        }else{
            newArray = array;
        }
        if(!type){type = 1;}
        return newArray.sort(function (x, y) {
            switch(type){
                case 2:
                    return y - x;
                    break;
                case 3:
                    var x1 = x.toUpperCase();
                    var x2 = y.toUpperCase();
                    if (x1 < x2) {
                        return -1;
                    }
                    if (x1 > x2) {
                        return 1;
                    }
                    return 0;
                    break;
                default:
                    return x - y;
                    break;
            }
        });
    }

    /*
        *  对象的深复制
        *  @param obj Object 要复制的对象
        *  @retrun Object 复制后的对象
    */
    __class.prototype.cloneObj = function (obj) {  
        var newObj = {};  
        if (obj instanceof Array) {  
            newObj = [];  
        }  
        for (var key in obj) {  
            var val = obj[key];  
            //newObj[key] = typeof val === 'object' ? arguments.callee(val) : val; //arguments.callee 在哪一个函数中运行，它就代表哪个函数, 一般用在匿名函数中。
            newObj[key] = typeof val === 'object' ? cloneObj(val): val;  
        }  
        return newObj;  
    };  

    return new __class();
})();